{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Doc2Vec\n",
    "\n",
    "Doc2vec is an adaptation of Word2Vec that allows us to learn document similarity. Doc2vec model by itself is an unsupervised method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from tqdm import tqdm\n",
    "tqdm.pandas(desc=\"progress-bar\")\n",
    "from gensim.models import Doc2Vec\n",
    "from sklearn import utils\n",
    "from sklearn.model_selection import train_test_split\n",
    "import gensim\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from gensim.models.doc2vec import TaggedDocument\n",
    "import re\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Consumer complaint narrative</th>\n",
       "      <th>Product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>When my loan was switched over to Navient i wa...</td>\n",
       "      <td>Student loan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>I tried to sign up for a spending monitoring p...</td>\n",
       "      <td>Credit card or prepaid card</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>My mortgage is with BB &amp; T Bank, recently I ha...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>The entire lending experience with Citizens Ba...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>My credit score has gone down XXXX points in t...</td>\n",
       "      <td>Credit reporting</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>I few months back I contacted XXXX  in regards...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>I '' m a victim of fraud and I have a file wit...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>My mortgage is owned by XXXX, we have painfull...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>I have been disputing a Bankruptcy on my credi...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54</th>\n",
       "      <td>Today I received a phone call from a number li...</td>\n",
       "      <td>Debt collection</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         Consumer complaint narrative  \\\n",
       "1   When my loan was switched over to Navient i wa...   \n",
       "2   I tried to sign up for a spending monitoring p...   \n",
       "7   My mortgage is with BB & T Bank, recently I ha...   \n",
       "14  The entire lending experience with Citizens Ba...   \n",
       "15  My credit score has gone down XXXX points in t...   \n",
       "17  I few months back I contacted XXXX  in regards...   \n",
       "28  I '' m a victim of fraud and I have a file wit...   \n",
       "30  My mortgage is owned by XXXX, we have painfull...   \n",
       "32  I have been disputing a Bankruptcy on my credi...   \n",
       "54  Today I received a phone call from a number li...   \n",
       "\n",
       "                                              Product  \n",
       "1                                        Student loan  \n",
       "2                         Credit card or prepaid card  \n",
       "7                                            Mortgage  \n",
       "14                                           Mortgage  \n",
       "15                                   Credit reporting  \n",
       "17  Credit reporting, credit repair services, or o...  \n",
       "28  Credit reporting, credit repair services, or o...  \n",
       "30                                           Mortgage  \n",
       "32  Credit reporting, credit repair services, or o...  \n",
       "54                                    Debt collection  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('Consumer_Complaints.csv')\n",
    "df = df[['Consumer complaint narrative','Product']]\n",
    "df = df[pd.notnull(df['Consumer complaint narrative'])]\n",
    "df.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(318718, 2)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Consumer complaint narrative    0\n",
       "Product                         0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAuYAAAJ6CAYAAABkPYdrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3Xvc5WO9//HXm1JUThmSISopuyKNQ8cdyqnQgWIXkvbsSkln7b1tpV3ppKKdnUJDyqlEImyRktMohxQ/k5SJIqetrRLevz+ua5k196x77jVj7nV9ud/Px+N+rPW91nfd38/c95rv/fle3+v6XLJNRERERES0tVTrACIiIiIiIol5REREREQnJDGPiIiIiOiAJOYRERERER2QxDwiIiIiogOSmEdEREREdEAS84iIiIiIDkhiHhERERHRAUnMIyIiIiI64FGtA2hplVVW8dprr906jIiIiIh4BLvsssv+ZHvaRPtN6cR87bXXZvbs2a3DiIiIiIhHMEm/HWa/DGWJiIiIiOiAJOYRERERER2QxDwiIiIiogOSmEdEREREdEAS84iIiIiIDkhiHhERERHRAUnMIyIiIiI6IIl5REREREQHTOkFhvrdcdLpTY670k7bNTluRERERHRLeswjIiIiIjogiXlERERERAckMY+IiIiI6IAk5hERERERHTCSxFzSepIu7/v6X0n7SlpZ0tmSrquPK9X9JekQSXMkXSlpo77vtUfd/zpJe/S1P1/SVfU9h0jSKP5tERERERFLwkgSc9vX2t7Q9obA84F7gJOB/YBzbK8LnFO3AbYF1q1fM4HDACStDBwAbApsAhzQS+brPjP73rfNCP5pERERERFLRIuhLFsCv7b9W2BHYFZtnwW8uj7fETjaxUXAipJWB7YGzrZ9u+07gLOBbepry9u+0LaBo/u+V0RERERE57VIzHcBvlWfr2b7ZoD6uGptXwO4se89c2vbwtrnDmiPiIiIiHhYGGliLmkZYAfgxIl2HdDmxWgfFMNMSbMlzb711lsnCCMiIiIiYjRG3WO+LfAz23+s23+sw1Coj7fU9rnAmn3vmw7cNEH79AHtC7B9uO0ZtmdMmzbtIf5zIiIiIiKWjFEn5rsybxgLwKlAr7LKHsApfe271+osmwF31aEuZwJbSVqpTvrcCjizvna3pM1q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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2a3218a2be0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cnt_pro = df['Product'].value_counts()\n",
    "\n",
    "plt.figure(figsize=(12,4))\n",
    "sns.barplot(cnt_pro.index, cnt_pro.values, alpha=0.8)\n",
    "plt.ylabel('Number of Occurrences', fontsize=12)\n",
    "plt.xlabel('Product', fontsize=12)\n",
    "plt.xticks(rotation=90)\n",
    "plt.show();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The classes are imbalanced. However, a naive classifier that predicts everything to be Debt collection will only achieve over 20% accuracy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Text preprocessing\n",
    "\n",
    "Below we define a function to convert text to lower-case and strip punctuation/symbols from words and so on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bs4 import BeautifulSoup\n",
    "def cleanText(text):\n",
    "    text = BeautifulSoup(text, \"lxml\").text\n",
    "    text = re.sub(r'\\|\\|\\|', r' ', text) \n",
    "    text = re.sub(r'http\\S+', r'<URL>', text)\n",
    "    text = text.lower()\n",
    "    text = text.replace('x', '')\n",
    "    return text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "df['Consumer complaint narrative'] = df['Consumer complaint narrative'].apply(cleanText)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'when my loan was switched over to navient i was never told that i had a deliquint balance because with  i did not. when going to purchase a vehicle i discovered my credit score had been dropped from the  into the . i have been faithful at paying my student loan. i was told that navient was the company i had delinquency with. i contacted navient to resolve this issue you and kept being told to just contact the credit bureaus and epalin the situation and maybe they could help me. i was so angry that i just hurried and paid the balance off and then after tried to dispute the delinquency with the credit bureaus. i have had so much trouble bringing my credit score back up.'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['Consumer complaint narrative'][1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(318718, 2)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Re-arrange the index of the table. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.index = range(318718)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Consumer complaint narrative</th>\n",
       "      <th>Product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>when my loan was switched over to navient i wa...</td>\n",
       "      <td>Student loan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>i tried to sign up for a spending monitoring p...</td>\n",
       "      <td>Credit card or prepaid card</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>my mortgage is with bb &amp; t bank, recently i ha...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>the entire lending eperience with citizens ban...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>my credit score has gone down  points in the l...</td>\n",
       "      <td>Credit reporting</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>i few months back i contacted   in regards to ...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>i '' m a victim of fraud and i have a file wit...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>my mortgage is owned by , we have painfully de...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>i have been disputing a bankruptcy on my credi...</td>\n",
       "      <td>Credit reporting, credit repair services, or o...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>today i received a phone call from a number li...</td>\n",
       "      <td>Debt collection</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                        Consumer complaint narrative  \\\n",
       "0  when my loan was switched over to navient i wa...   \n",
       "1  i tried to sign up for a spending monitoring p...   \n",
       "2  my mortgage is with bb & t bank, recently i ha...   \n",
       "3  the entire lending eperience with citizens ban...   \n",
       "4  my credit score has gone down  points in the l...   \n",
       "5  i few months back i contacted   in regards to ...   \n",
       "6  i '' m a victim of fraud and i have a file wit...   \n",
       "7  my mortgage is owned by , we have painfully de...   \n",
       "8  i have been disputing a bankruptcy on my credi...   \n",
       "9  today i received a phone call from a number li...   \n",
       "\n",
       "                                             Product  \n",
       "0                                       Student loan  \n",
       "1                        Credit card or prepaid card  \n",
       "2                                           Mortgage  \n",
       "3                                           Mortgage  \n",
       "4                                   Credit reporting  \n",
       "5  Credit reporting, credit repair services, or o...  \n",
       "6  Credit reporting, credit repair services, or o...  \n",
       "7                                           Mortgage  \n",
       "8  Credit reporting, credit repair services, or o...  \n",
       "9                                    Debt collection  "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.rename(columns = {'Consumer complaint narrative':'narrative'}, inplace = True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>narrative</th>\n",
       "      <th>Product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>when my loan was switched over to navient i wa...</td>\n",
       "      <td>Student loan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>i tried to sign up for a spending monitoring p...</td>\n",
       "      <td>Credit card or prepaid card</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>my mortgage is with bb &amp; t bank, recently i ha...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>the entire lending eperience with citizens ban...</td>\n",
       "      <td>Mortgage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>my credit score has gone down  points in the l...</td>\n",
       "      <td>Credit reporting</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           narrative  \\\n",
       "0  when my loan was switched over to navient i wa...   \n",
       "1  i tried to sign up for a spending monitoring p...   \n",
       "2  my mortgage is with bb & t bank, recently i ha...   \n",
       "3  the entire lending eperience with citizens ban...   \n",
       "4  my credit score has gone down  points in the l...   \n",
       "\n",
       "                       Product  \n",
       "0                 Student loan  \n",
       "1  Credit card or prepaid card  \n",
       "2                     Mortgage  \n",
       "3                     Mortgage  \n",
       "4             Credit reporting  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we define a function to label each complaint narrative. And the TaggedDocument is an object-type to encapsulate a text-example function that helps to associate a tag/number with each document of the training corpus. In our case, the tag is simply the zero based line number."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gensim.models import doc2vec\n",
    "\n",
    "def label_sentences(corpus, label_type):\n",
    "    \"\"\"\n",
    "    Gensim's Doc2Vec implementation requires each document/paragraph to have a label associated with it.\n",
    "    We do this by using the TaggedDocument method. The format will be \"TRAIN_i\" or \"TEST_i\" where \"i\" is\n",
    "    a dummy index of the complaint narrative.\n",
    "    \"\"\"\n",
    "    labeled = []\n",
    "    for i, v in enumerate(corpus):\n",
    "        label = label_type + '_' + str(i)\n",
    "        labeled.append(doc2vec.TaggedDocument(v.split(), [label]))\n",
    "    return labeled"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(df.narrative, df.Product, random_state=0, test_size=0.3)\n",
    "X_train = label_sentences(X_train, 'Train')\n",
    "X_test = label_sentences(X_test, 'Test')\n",
    "all_data = X_train + X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "318718"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(all_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the training corpus."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[TaggedDocument(words=['i', 'am', 'having', 'trouble', 'repaying', 'my', 'student', 'loans', 'for', 'my', 'account', '.', 'due', 'to', 'economic', 'hardship', 'i', 'have', 'asked', 'for', 'an', 'income-driven', 'repayment', 'plan', 'and', 'received', 'an', 'offer', 'of', '{$180.00}', 'on', '2016.', 'however,', 'fed', 'loan', 'servicing', 'on', ',', '2016', 'sent', 'me', 'an', 'invoice', 'in', 'the', 'amount', 'of', '{$1300.00}', 'which', 'includes', 'an', 'amount', 'past', 'due', 'of', '{$610.00}', 'and', 'a', 'current', 'payment', 'of', '{$720.00}.', 'please', 'note', 'that', 'for', 'me', 'it', 'is', 'a', 'stretch', 'for', 'me', 'to', 'pay', 'the', 'income-driven', 'repayment', 'plan', 'and', 'received', 'an', 'offer', 'of', '{$180.00}', 'but', 'i', 'am', 'willing', 'to', 'do', 'the', 'sacrifice.', 'however,', 'it', 'would', 'be', 'a', 'financial', 'burden', 'to', 'pay', 'the', 'amount', 'asked', 'for', 'on', 'the', 'invoice', 'sent', 'by', 'fed', 'loan', 'servicing', 'on', ',', '2016', 'in', 'the', 'amount', 'of', '{$1300.00}.', 'furthermore,', 'reneging', 'on', 'the', 'income-driven', 'repayment', 'plan', 'offer', 'of', '{$180.00}', 'and', 'asking', 'me', 'now', 'to', 'pay', 'the', 'amount', 'of', '{$1300.00}', 'which', 'includes', 'an', 'amount', 'past', 'due', 'of', '{$610.00}', 'and', 'a', 'current', 'payment', 'of', '{$720.00}', 'would', 'be', 'detrimental', 'to', 'me.', 'by', 'reneging', 'fedloan', 'services', 'does', 'not', 'take', 'into', 'account', 'the', 'fact', 'that', 'i', 'have', 'no', 'discretionary', 'income', 'to', 'pay', 'my', 'student', 'loans', 'according', 'to', '.', 'i', 'have', 'asked', 'for', 'a', 'minimum', 'before', 'but', 'the', 'provider', 'has', 'sent', 'collections', 'notices', 'as', 'well', 'as', 'threats', 'of', 'garnishment.', 'likewise,', 'i', 'have', 'asked', 'for', 'as', 'i', 'am', 'a', 'but', 'i', 'as', 'ill', 'advised', 'by', 'fed', 'loan', 'servicing', 'that', 'i', 'do', 'not', 'qualify', 'even', 'though', 'i', 'work', 'in', 'an', '.'], tags=['Train_0']),\n",
       " TaggedDocument(words=['so', 'first', 'off', 'let', 'me', 'start', 'off', 'by', 'saying.', 'i', 'have', 'a', 'so', 'if', 'this', 'is', 'hard', 'to', 'understand', 'thats', 'why.', 'so', 'my', 'story', 'now.', 'i', 'have', 'a', 'credit', 'card', 'with', 'capital', 'one.', 'i', 'am', 'trying', 'to', 'fi', 'my', 'charging', 'privileges', 'and', 'restricted', 'status', 'on', 'my', 'account.', 'i', 'have', 'sent', 'them', 'certified', 'letters,', 'i', 'emailed', 'them,', 'and', 'i', 'have', 'called', 'them.', 'but', 'i', 'feel', 'like', 'i', 'am', 'getting', 'treated', 'with', 'neglection.', 'they', 'told', 'me', 'i', 'was', 'suppose', 'to', 'pay', 'off', 'my', 'bill', 'by', 'a', 'certain', 'date.', 'they', 'also', 'said', 'i', 'have', 'recovered', 'a', 'award', 'letter', 'to', 'get', 'my', 'privileges', 'back.', 'but', 'sense', 'i', 'did', \"n't\", 'pay', 'the', 'bill', 'by', 'the', 'certain', 'date', 'they', 'revoked', 'my', 'privileges.', 'but', 'i', 'am', 'disputing', 'this', 'item', 'for', 'you', 'to', 'review', 'because', 'i', 'did', 'pay', 'this', 'item', 'by', 'a', 'certain', 'date.', 'but', 'the', 'only', 'problem', 'is', 'there', 'posting', 'period', 'took', 'longer', 'then', 'usual.', 'so', 'they', 'revoked', 'my', 'privileges.', 'i', 'am', 'willing', 'to', 'work', 'with', 'this', 'creditor', 'i', 'tried.', 'but', 'they', 'did', \"n't\", 'work', 'with', 'me.', 'so', 'if', 'they', 'do', \"n't\", 'work', 'with', 'me.', 'i', 'will', 'be', 'releasing', 'a', 'public', 'press', 'release', 'online', 'about', 'this', 'company', 'for', 'neglect', 'ion', 'and', 'unable', 'to', 'work', 'with', 'someone', 'that', 'has', 'a', 'that', 'just', 'wants', 'to', 'rebuild', 'there', 'credit.', 'so', 'if', 'you', 'can', 'work', 'with', 'this', 'creditor', 'and', 'get', 'them', 'to', 'work', 'with', 'me', 'that', 'would', 'be', 'progress.', 'i', 'feel', 'like', 'i', 'have', 'been', 'treated', 'with', 'neglection', 'here.', 'thanks'], tags=['Train_1'])]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_data[:2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Training the model\n",
    "\n",
    "We'll instantiate a Doc2Vec model-Distributed Bag of Words (DBOW). In the Word2Vec architecture, the two algorithm names are “continuous bag of words” (cbow) and “skip-gram” (sg); in the Doc2Vec architecture, the corresponding algorithms are “distributed bag of words” (dbow) and “distributed memory” (dm)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DBOW\n",
    "\n",
    "DBOW is the Doc2Vec model analogous to Skip-gram model in Word2Vec. The paragraph vectors are obtained by training a neural network on the task of predicting a probability distribution of words in a paragraph given a randomly-sampled word from the paragraph.\n",
    "\n",
    "Training a Doc2Vec model is rather straight forward in Gensim, we initialize the model and train for 30 epochs:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "dm =0 means ‘distributed bag of words’ (DBOW), set min_count=2 means ignoring all words with total frequency lower than this, size=100 is dimensionality of the generated feature vectors, alpha=0.025 is the initial alpha rate, learning rate will linearly drop to min_alpha as training progresses. And then we build a vocabulary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 318718/318718 [00:00<00:00, 2537947.09it/s]\n"
     ]
    }
   ],
   "source": [
    "model_dbow = Doc2Vec(dm=0, vector_size=300, negative=5, min_count=1, alpha=0.065, min_alpha=0.065)\n",
    "model_dbow.build_vocab([x for x in tqdm(all_data)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 318718/318718 [00:00<00:00, 2722501.94it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2600616.66it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2375667.86it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399382.02it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3261864.60it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3449833.63it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2406732.26it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2549515.45it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2722773.66it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2970746.29it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399338.80it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2088753.55it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3213755.54it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2864054.24it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2957273.91it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2913681.93it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2167860.25it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2060997.66it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2678169.32it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3192213.80it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1018820.26it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399390.67it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399312.87it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2913364.43it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2522983.31it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2671185.61it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399330.16it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3399330.16it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2913713.68it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2913828.00it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 33min 18s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "for epoch in range(30):\n",
    "    model_dbow.train(utils.shuffle([x for x in tqdm(all_data)]), total_examples=len(all_data), epochs=1)\n",
    "    model_dbow.alpha -= 0.002\n",
    "    model_dbow.min_alpha = model_dbow.alpha"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a function to get the vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_vectors(model, corpus_size, vectors_size, vectors_type):\n",
    "    \"\"\"\n",
    "    Get vectors from trained doc2vec model\n",
    "    :param doc2vec_model: Trained Doc2Vec model\n",
    "    :param corpus_size: Size of the data\n",
    "    :param vectors_size: Size of the embedding vectors\n",
    "    :param vectors_type: Training or Testing vectors\n",
    "    :return: list of vectors\n",
    "    \"\"\"\n",
    "    vectors = np.zeros((corpus_size, vectors_size))\n",
    "    for i in range(0, corpus_size):\n",
    "        prefix = vectors_type + '_' + str(i)\n",
    "        vectors[i] = model.docvecs[prefix]\n",
    "    return vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_vectors_dbow = get_vectors(model_dbow, len(X_train), 300, 'Train')\n",
    "test_vectors_dbow = get_vectors(model_dbow, len(X_test), 300, 'Test')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='multinomial',\n",
       "          n_jobs=1, penalty='l2', random_state=None, solver='lbfgs',\n",
       "          tol=0.0001, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "logreg = LogisticRegression(multi_class='multinomial', solver = 'lbfgs')\n",
    "logreg.fit(train_vectors_dbow, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6882425535475234"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logreg.score(test_vectors_dbow, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_dbow.save('d2v_model_dbow.doc2vec')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Distributed Memory\n",
    "\n",
    "Distributed Memory (DM) acts as a memory that remembers what is missing from the current context — or as the topic of the paragraph. While the word vectors represent the concept of a word, the document vector intends to represent the concept of a document.\n",
    "\n",
    "We again instantiate a Doc2Vec model with a vector size with 100 words and iterating over the training corpus 30 times."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 318718/318718 [00:00<00:00, 1621798.90it/s]\n"
     ]
    }
   ],
   "source": [
    "model_dm = Doc2Vec(dm=1, dm_mean=1, vector_size=300, window=10, negative=5, min_count=1, workers=5, alpha=0.065, min_alpha=0.065)\n",
    "model_dm.build_vocab([x for x in tqdm(all_data)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 318718/318718 [00:00<00:00, 2764131.19it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1066654.90it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1880859.47it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1103720.83it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1070251.82it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 905616.33it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2172341.30it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 875676.71it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1535611.15it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 987147.58it/s] \n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1190525.12it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1836549.06it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1963555.23it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1123252.95it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1901808.46it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2648902.00it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1399458.12it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1711163.37it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3116360.38it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 3591405.62it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1831448.89it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2176986.26it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1168642.98it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2563414.55it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1858905.35it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1181675.70it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1164360.69it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 769659.58it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 1897995.78it/s]\n",
      "100%|██████████| 318718/318718 [00:00<00:00, 2408128.30it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 56min 23s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "for epoch in range(30):\n",
    "    model_dm.train(utils.shuffle([x for x in tqdm(all_data)]), total_examples=len(all_data), epochs=1)\n",
    "    model_dm.alpha -= 0.002\n",
    "    model_dm.min_alpha = model_dm.alpha"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_vectors_dm = get_vectors(model_dm, len(X_train), 300, 'Train')\n",
    "test_vectors_dm = get_vectors(model_dm, len(X_test), 300, 'Test')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='multinomial',\n",
       "          n_jobs=1, penalty='l2', random_state=None, solver='lbfgs',\n",
       "          tol=0.0001, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logreg.fit(train_vectors_dm, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6646690930388219"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logreg.score(test_vectors_dm, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_dm.save('d2v_model_dm.doc2vec')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "# model_dbow = Doc2Vec.load('d2v_model_dbow.doc2vec')\n",
    "# model_dm = Doc2Vec.load('d2v_model_dm.doc2vec')\n",
    "model_dbow.delete_temporary_training_data(keep_doctags_vectors=True, keep_inference=True)\n",
    "model_dm.delete_temporary_training_data(keep_doctags_vectors=True, keep_inference=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_concat_vectors(model1,model2, corpus_size, vectors_size, vectors_type):\n",
    "    vectors = np.zeros((corpus_size, vectors_size))\n",
    "    for i in range(0, corpus_size):\n",
    "        prefix = vectors_type + '_' + str(i)\n",
    "        vectors[i] = np.append(model1.docvecs[prefix],model2.docvecs[prefix])\n",
    "    return vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_vecs_dbow_dm = get_concat_vectors(model_dbow,model_dm, len(X_train), 600, 'Train')\n",
    "test_vecs_dbow_dm = get_concat_vectors(model_dbow,model_dm, len(X_test), 600, 'Test')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 19min 18s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "logreg = LogisticRegression()\n",
    "logreg.fit(train_vecs_dbow_dm, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7055199966532798"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logreg.score(test_vecs_dbow_dm, y_test)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
